// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "ReplicationGraph.h"
#include "Define/LineReplicationType.h"
#include "LineReplicationGraphObject.generated.h"

class ULRG_DebugComponent;
class ULRG_Node_GridSpatial;

UCLASS(transient)
class LINEREPLICATIONGRAPH_API ULineReplicationGraph :public UReplicationGraph
{
	GENERATED_BODY()

public:
	static ULineReplicationGraph* Get(const UObject* WorldContext);
	ULineReplicationGraph();

	virtual void ResetGameWorldState() override;
	virtual void InitGlobalActorClassSettings() override;
	virtual void InitGlobalGraphNodes() override;
	virtual void InitConnectionGraphNodes(UNetReplicationGraphConnection* RepGraphConnection) override;
	virtual void AddNetworkActor(AActor* Actor) override;
	virtual void RouteAddNetworkActorToNodes(const FNewReplicatedActorInfo& ActorInfo, FGlobalActorReplicationInfo& GlobalInfo) override;
	virtual void RouteRemoveNetworkActorToNodes(const FNewReplicatedActorInfo& ActorInfo) override;
	
	virtual int32 ServerReplicateActors(float DeltaSeconds) override;
public:
	void AddDebugComponent(ULRG_DebugComponent* Component);
	void RemoveDebugComponent(ULRG_DebugComponent* Component);
protected:
	ELineReplicationType GetClassReplicationType(UClass* Class);
public:
	TMap<FName, FActorRepListRefView> AlwaysRelevantStreamingLevelActors;
protected:
	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category=Config)
	float GridCellSize = 4800;
	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category=Config)
	float PawnCullDistance = 6400;
	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category=Config)
	float DestructionInfoMaxDist = 15000;
	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category=Config)
    TSet<UClass*> NotRoutedClasses;
	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category=Config)
	TSet<UClass*> RelevantAllServerClasses;
    UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category=Config)
    TSet<UClass*> RelevantAllInLineClasses;
protected:
	UPROPERTY()
	ULRG_Node_GridSpatial* GridSpatialNode;
	UPROPERTY()
	UReplicationGraphNode_ActorList* AlwaysRelevantNode = nullptr;
	UPROPERTY()
	UReplicationGraphNode_ActorList* AlwaysRelevantToLineNode = nullptr;
	
protected:
	TClassMap<ELineReplicationType> ClassRepNodePolicies;
protected:
	UPROPERTY()
	TArray<TObjectPtr<AActor>> ActorsWithoutNetConnection;

	UPROPERTY()
	TSet<TObjectPtr<AActor>> ActorsNoInLine;

	UPROPERTY()
	TSet<ULRG_DebugComponent*> DebugComponents;
};